from flask import Blueprint, request, render_template, jsonify, json, session, redirect

import pandas as pd
import os
import verfy
from models import Uploadhomework, Homework, Student
from collections import OrderedDict
from exts import db
# from django.core.paginator import Paginator  # 注释掉Django分页器


from Utils.paginator import SimplePaginator
from werkzeug.security import generate_password_hash, check_password_hash

bp = Blueprint("uploadhomework", __name__, url_prefix="/uploadhomework")


@bp.before_request
def before_request():
    """作业上传蓝图权限检查"""
    # 检查用户是否登录
    if session.get('is_login') != 'true':
        return redirect('/login')
    
    # 检查用户角色
    user_role = session.get('role')
    if user_role not in ['teacher', 'student']:
        return jsonify({'error': '用户角色无效'}), 403


@bp.route("/")
def student_index():
    return "这是作业详情界面"


@bp.route("/list1", methods=["GET"])
def uploadhomework_list1():
    # 1。get查找 根据主键查找
    # teacher = Teacher.query.get(1001)
    # print(teacher.name)
    # 2。fliter_by查找
    # students = Student.query.filter_by(class_id = "230101")
    role = session.get('role')
    hnumber = request.args.get("hnumber")
    upload_homeworks = []
    bigclass = request.args.get("bigsclass")
    stu_id = request.args.get("stu_id")
    class_id = request.args.get("class_id")
    if len(str(hnumber)) == 0:
        hnumber = None
    if len(str(bigclass)) == 0:
        bigclass = None
    if len(str(stu_id)) == 0:
        stu_id = None
    if len(str(class_id)) == 0:
        class_id = None
    if role == 'teacher':
        if hnumber is not None:
            if stu_id is not None:
                upload_homeworks = Uploadhomework.query.filter_by(hnumber=hnumber, sid=stu_id).all()
            else:
                upload_homeworks = Uploadhomework.query.filter_by(hnumber=hnumber).all()
        else:
            if stu_id is not None:
                upload_homeworks = Uploadhomework.query.filter_by(sid=stu_id).all()
            else:
                upload_homeworks = Uploadhomework.query.all()
    if role == 'student':
        if hnumber is not None:
            upload_homeworks = Uploadhomework.query.filter_by(hnumber=hnumber, sid=session.get('user_id')).all()
        else:
            upload_homeworks = Uploadhomework.query.filter_by(sid=session.get('user_id')).all()
    new_upload_homeworks = []
    if bigclass is not None:
        for upload_homework in upload_homeworks:
            if upload_homework.is_this_class(bigclass) == 1:
                new_upload_homeworks.append(upload_homework)
        upload_homeworks = new_upload_homeworks
    new_upload_homeworks = []
    if class_id is not None:
        for upload_homework in upload_homeworks:
            if upload_homework.is_this_class1(class_id) == 1:
                new_upload_homeworks.append(upload_homework)
        upload_homeworks = new_upload_homeworks
    pageIndex = request.args.get("pageIndex")
    pageSize = request.args.get("pageSize")
    out_data = []
    data = []
    i = 0
    for uploadhomework in upload_homeworks:
        upload_homework_json = uploadhomework.to_json()
        upload_homework_json['is_copy'] = uploadhomework.get_copy_result()
        data.append(upload_homework_json)
        i += 1
    #  out_data.append(OrderedDict(count=i))
    # out_data.append(OrderedDict(data=data))
    # return OrderedDict(code=0, count=i, data=data)
    # 使用自定义分页器
    if pageSize and int(pageSize) > 0:
        paginator = SimplePaginator(data, pageSize)
        page_data = paginator.page(pageIndex)
    else:
        page_data = data
    
    return OrderedDict(code=0, count=i, data=page_data)



@bp.route("/test", methods=["GET", "POST"])
def uploadhomework_test():
    """代码作业测试功能"""
    try:
        data = request.json
        print(data.get("homeworkpath"))
        code_path = data.get("homeworkpath")
        homework = Homework.query.filter_by(ID=int(data.get("hnumber"))).first()
        
        if not homework:
            return json.dumps({'code': 1, 'msg': '作业不存在'})
            
        path = homework.attachment_path
        print(path)
        
        # 检查测试用例文件是否存在
        input_file = path + "/input.txt"
        output_file = path + "/output.txt"
        
        if not os.path.exists(input_file) or not os.path.exists(output_file):
            return json.dumps({'code': 2, 'msg': '该作业暂无测试用例，请联系老师添加测试用例。'})
        
        # 执行测试
        num = 0
        f = open(input_file, 'r')
        line = f.readline()
        while line:
            num += 1
            line = f.readline()
        # 从请求数据中获取学生的班级信息和用户ID
        student_class_id = data.get("sclass2") or session.get("class_id2")
        student_user_id = data.get("sid") or session.get("user_id")
        
        a = verfy.verify(path + "/input.txt", path + "/output.txt", student_class_id, student_user_id)
        
        # 处理verfy.verify返回的结果
        if isinstance(a, list) and len(a) >= 1:
            if a[0] == -1:
                # 错误情况，返回错误信息
                error_msg = a[1] if len(a) > 1 else "测试执行失败"
                return json.dumps({'code': 2, 'msg': error_msg})
            else:
                # 正常情况，a[0]就是分数（0-100）
                grade = int(a[0])
        else:
            # 如果返回格式不正确，使用默认逻辑
            grade = 0
        
        uploadhomework = Uploadhomework.query.filter_by(ID=data.get("ID")).first()
        if uploadhomework:
            uploadhomework.grade = grade
            db.session.commit()
            
        return json.dumps({'code': 0, 'msg': grade})
        
    except Exception as e:
        print(f"测试错误: {str(e)}")
        import traceback
        traceback.print_exc()
        return json.dumps({'code': 1, 'msg': f'测试失败: {str(e)}'})


@bp.route("/list")
def uploadhomework_list():
    print("作业情况列表")
    # 1。get查找 根据主键查找
    # teacher = Teacher.query.get(1001)
    # print(teacher.name)
    # 2。fliter_by查找
    # students = Student.query.filter_by(class_id = "230101")
    return render_template('uploadhomework.html')

@bp.route("/ehlist")
def uploadhomework_ehlist():
    """教师专用：本次作业情况列表"""
    # 检查是否为教师
    if session.get('role') != 'teacher':
        return jsonify({'error': '权限不足，仅教师可以访问此功能'}), 403
    
    print("本次作业情况列表")
    return render_template('teacher_homework.html')

@bp.route("/teacher_view")
def teacher_homework_view():
    """教师专用：作业查看和打分页面"""
    # 检查是否为教师
    if session.get('role') != 'teacher':
        return jsonify({'error': '权限不足，仅教师可以访问此功能'}), 403
    
    print("教师作业查看管理")
    return render_template('teacher_homework_view.html')

@bp.route("/teacher_list", methods=["GET"])
def teacher_uploadhomework_list():
    """教师专用：获取作业提交列表API"""
    # 检查是否为教师
    if session.get('role') != 'teacher':
        return jsonify({'error': '权限不足，仅教师可以访问此功能'}), 403
    
    try:
        # 获取分页参数
        page_index = int(request.args.get("pageIndex", 1))
        page_size = int(request.args.get("pageSize", 10))
        
        # 获取查询参数
        hnumber = request.args.get("hnumber", "")
        bigsclass = request.args.get("bigsclass", "")
        class_id = request.args.get("class_id", "")
        stu_id = request.args.get("stu_id", "")
        
        # 构建查询
        query = Uploadhomework.query.join(Student)
        
        # 添加过滤条件
        if hnumber:
            query = query.filter(Uploadhomework.hnumber == hnumber)
        if bigsclass:
            query = query.filter(Student.class_id2 == bigsclass)
        if class_id:
            query = query.filter(Student.class_id1 == class_id)
        if stu_id:
            query = query.filter(Student.ID == stu_id)
        
        # 分页查询
        total = query.count()
        offset = (page_index - 1) * page_size
        uploadhomeworks = query.offset(offset).limit(page_size).all()
        
        # 转换为字典格式
        data = []
        for upload in uploadhomeworks:
            upload_dict = upload.to_json()
            # 添加抄袭检测结果
            upload_dict['is_copy'] = "未检测"  # 默认值，可以根据实际情况修改
            data.append(upload_dict)
        
        return jsonify({
            'code': 200,
            'msg': '获取成功',
            'count': total,
            'data': data
        })
        
    except Exception as e:
        print(f"获取教师作业列表失败: {str(e)}")
        return jsonify({
            'code': 500,
            'msg': f'获取作业列表失败: {str(e)}',
            'count': 0,
            'data': []
        })

@bp.route("/update_text_grade", methods=["POST"])
def update_text_grade():
    """教师专用：更新文本作业成绩"""
    # 检查是否为教师
    if session.get('role') != 'teacher':
        return jsonify({'success': False, 'message': '权限不足，仅教师可以访问此功能'}), 403
    
    try:
        data = request.get_json()
        upload_id = data.get('upload_id')
        grade = data.get('grade')
        
        # 验证参数
        if not upload_id or grade is None:
            return jsonify({'success': False, 'message': '参数不完整'})
        
        if not isinstance(grade, int) or grade < 0 or grade > 100:
            return jsonify({'success': False, 'message': '成绩必须是0-100之间的整数'})
        
        # 查找作业提交记录
        upload_homework = Uploadhomework.query.get(upload_id)
        if not upload_homework:
            return jsonify({'success': False, 'message': '作业提交记录不存在'})
        
        # 检查是否为文本作业
        if upload_homework.submission_type != 'text':
            return jsonify({'success': False, 'message': '只能对文本作业进行手动评分'})
        
        # 更新成绩
        upload_homework.grade = grade
        db.session.commit()
        
        return jsonify({'success': True, 'message': '评分更新成功'})
        
    except Exception as e:
        db.session.rollback()
        print(f"更新文本作业成绩失败: {str(e)}")
        return jsonify({'success': False, 'message': f'更新失败: {str(e)}'})


import numpy as np

@bp.route("/list2", methods=["GET"])
def uploadhomework_list2():
    # 获取作业编号
    hnumber = request.args.get("hnumber")

    # 查询数据库获取attachment_path
    homework = Homework.query.filter_by(ID=hnumber).first()
    if not homework:
        return jsonify({'code': 0, 'data': []})  # 返回一个空列表

    dir_path = homework.attachment_path
    data = []
    # 查找student表中的所有不同class_id2,存入class_id2_list

    class_id2_list = db.session.query(Student.class_id2).distinct().all()
    file_name_list = []
    for class_id2 in class_id2_list:
        # 将copy与class_id2组合成文件名，存入dir_path
        file_name_list.append('copy' + str(class_id2[0]))

    class_name = ''
    a=0
    for file_name in os.listdir(dir_path):
        print(file_name)
        for i in range(len(file_name_list)):
            if file_name.startswith(file_name_list[i]):
                print(file_name_list[i])
                if i < len(class_id2_list):
                    class_name = str(class_id2_list[i][0])
                else:
                    class_name = ""  # 或者设置一cd个默认值

                # class_name = str(class_id2_list[i][0])
                a=1
                break
        if a==0:
            continue
        a=0
        # if file_name.startswith('copy1'):
        #     class_name = '1'
        # elif file_name.startswith('copy3'):
        #     class_name = '3'
        # else:
        #     continue

        file_path = os.path.join(dir_path, file_name)

        # 使用pandas读取所有列
        df = pd.read_excel(file_path,  header=None, dtype=str)


        if df.empty:
            continue

        # 获取列数
        num_columns = len(df.columns)
        plagiarized_students=[]
        # 遍历每列
        for col_index in range(num_columns):
            version = df.iloc[0, col_index]
            column_data = df.iloc[1:, col_index].astype(str).tolist()
            column_data = [student for student in column_data if student != 'nan']
            plagiarized_students.append(column_data)

            # 创建一个数据行
            data_row = {
                'class_name': class_name,  # 班级名称
                'version': version,  # 版本号
                'plagiarized_students': column_data  # 抄袭学生学号
            }

            # 将数据行添加到data列表
            data.append(data_row)

    # 转换 int64 到 int
    def default(obj):
        if isinstance(obj, np.int64):
            return int(obj)
        raise TypeError(f"Object of type {type(obj).__name__} is not JSON serializable")

    # 使用OrderedDict创建一个有序字典
    response_data = OrderedDict([
        ('code', 0),
        # ('ID', len(data) + 1),
        ('data', data),
    ])


    return json.dumps(response_data, default=default)
